﻿using Rhino;
using Rhino.DocObjects;
using Rhino.Input.Custom;
using System;
using System.Collections.Generic;
using System.Linq;

namespace AiMoRhino.ScriptInstance.LinkSelect
{
    abstract class LinkedItemBase
    {
        public abstract bool IsMultiple { get; }
        public LinkType CurrentLinkType { get; }
        public LinkedItemBase(LinkType currentLinkType)
        {
            CurrentLinkType = currentLinkType;
        }
        public abstract bool HasLinkedObject { get; }

        public abstract IEnumerable<Guid> AllIDs { get; }
        public abstract void ClearLink();
        public abstract bool BuildLink();
        public abstract bool GetLinkedGeometry();

        protected RhinoObject Find(Guid id)
        {
            return RhinoDoc.ActiveDoc.Objects.FindId(id);
        }

        void ClearSelect()
        {
            RhinoDoc.ActiveDoc.Objects.UnselectAll();
        }

        protected bool GetMultipleObject(out RhinoObject[] rhinoObjects, ObjectType objectType, string name, GetObject get)
        {
            //if(RhinoApp.InvokeRequired)
            //{
            //    bool re2 = false;
            //    RhinoObject[] rhinoObjects2 = null;
            //    Action ac = new Action(() => { re2 = GetMultipleObject(out rhinoObjects2 , objectType, name, get); });
            //    RhinoApp.InvokeAndWait(ac);
            //    rhinoObjects = rhinoObjects2;
            //    return re2;
            //}
            get.SetCommandPrompt($"请选择多个 {name}");
            get.EnablePreSelect(true, true);
            get.GeometryFilter = objectType;
            get.SubObjectSelect = false;
            bool re = get.GetMultiple(1, 0) == Rhino.Input.GetResult.Object && get.ObjectCount > 0;
            if (re)
                rhinoObjects = get.Objects().Select(x => x.Object()).ToArray();
            else
                rhinoObjects = null;
            ClearSelect();
            return re;
        }

        protected bool GetOneObject(out RhinoObject rhinoObject, ObjectType objectType, string name, GetObject get)
        {
            //if (RhinoApp.InvokeRequired)
            //{
            //    bool re2 = false;
            //    RhinoObject rhinoObject2 = null;
            //    Action ac = new Action(() => { re2 = GetOneObject(out rhinoObject2, objectType, name, get); });
            //    RhinoApp.InvokeAndWait(ac);
            //    rhinoObject = rhinoObject2;
            //    return re2;
            //}
            get.SetCommandPrompt($"请选择一个{name}");
            get.EnablePreSelect(true, true);
            get.GeometryFilter = objectType;
            get.SubObjectSelect = false;
            bool re = get.Get() == Rhino.Input.GetResult.Object && get.ObjectCount > 0;
            if (re)
                rhinoObject = get.Object(0).Object();
            else
                rhinoObject = null;
            ClearSelect();
            return re;
        }

        public override string ToString()
        {
            string typeName = CurrentTypeName();
            if (IsMultiple) typeName += "[]";
            if (HasLinkedObject)
            {
                return $"{typeName} 已关联";
            }
            else
            {
                return $"{typeName} 未建立关联";
            }
        }

        string CurrentTypeName()
        {
            switch (CurrentLinkType)
            {
                case LinkType.RhinoObject:
                    return "RhinoObject";
                case LinkType.Point3d:
                    return "Point3d";
                case LinkType.Polyline:
                    return "Polyine";
                case LinkType.Circle:
                    return "Circle";
                case LinkType.Line:
                    return "Line";
                case LinkType.Curve:
                    return "Curve";
                case LinkType.Mesh:
                    return "Mesh";
                case LinkType.Brep:
                    return "Brep";
                case LinkType.Extrusion:
                    return "Extrusion";
                case LinkType.Surface:
                    return "Surface";
                case LinkType.InstanceObject:
                    return "InstanceObject";
                default: return "Unknown";
            }
        }
    }
}
